﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ProgNetComponentsDx.Forms;
using Wydatki.WRK.Lotto.DataSets;
using Wydatki.Tools.Lotto;
using ProgNetComponentsDx.Data;

namespace Wydatki.WRK.Lotto
{
    public partial class FormStatystykiLosowan : MyBaseSqlCeGridForm
    {
        private FormBackgroundWorkMultiThread multiThreadForm;
        
        object lockDs = new object();
        LottoStatystykiLosowanDataSet copyDs = new LottoStatystykiLosowanDataSet();
        object lockId = new object();
        List<object[]> NewItems = new List<object[]>();

        DataRow[] rows;

        public FormStatystykiLosowan()
        {
            InitializeComponent();
        }

        private bool ValidateActions()
        {
            bool result = true;
            if (result)
            {
                DataRow[] rows = lottoStatystykiLosowanDataSet1.WRK_LOTTO_STATYSTYKI_LOSOWAN.Select("LICZ = 1");
                string type;
                ActionLottoBase action;
                foreach (DataRow r in rows)
                {
                    if (!r.CanRead())
                        continue;
                    r.ClearErrors();
                    type = r["WRK_LSL_TYP"].AsString();
                    action = ActionLottoBase.GetActionForLosowania(type);
                    if (action == null)
                    {
                        r.SetColumnError("WRK_LSL_TYP", "Zły typ");
                        result = false;
                    }
                    else
                    {
                        if (!action.ValidateParams(r))
                            result = false;
                    }
                }
            }
            return result;
        }
        protected override void OnLoad()
        {
            base.OnLoad();
            if (!this.IsDesignMode())
            {
                this.Controls.Remove(gcMain);
                gcMain.Dock = DockStyle.Fill;
                this.splitContainerControl1.Panel1.Controls.Add(gcMain);
                gcMain.BringToFront();
            }
        }
        private void btnZaznaczWszystkie_Click(object sender, EventArgs e)
        {
            DataRow[] rows = lottoStatystykiLosowanDataSet1.WRK_LOTTO_STATYSTYKI_LOSOWAN.Select();
            ZaznaczOdznacz(rows, true);
        }
        private void ZaznaczOdznacz(DataRow[] rows, bool zaznacz)
        {
            foreach (DataRow r in rows)
                r["LICZ"] = zaznacz;
        }

        private void btnZaznaczNiewyliczone_Click(object sender, EventArgs e)
        {
            DataRow[] rows = lottoStatystykiLosowanDataSet1.WRK_LOTTO_STATYSTYKI_LOSOWAN.Select("WRK_LSL_ILOSC IS NULL");
            ZaznaczOdznacz(rows, true);
        }

        private void btnOdznaczWszystkie_Click(object sender, EventArgs e)
        {
            DataRow[] rows = lottoStatystykiLosowanDataSet1.WRK_LOTTO_STATYSTYKI_LOSOWAN.Select();
            ZaznaczOdznacz(rows, false);
        }

        private void btnAkcjePrzelicz_Click(object sender, EventArgs e)
        {
            FinishEdit();
            if (!ValidateActions())
            {
                this.ShowDxInfoDialog("Błąd walidacji.");
                return;
            }

            copyDs = lottoStatystykiLosowanDataSet1.Copy() as LottoStatystykiLosowanDataSet;
            rows = copyDs.WRK_LOTTO_STATYSTYKI_LOSOWAN.Select("LICZ = 1");
            foreach (DataRow r in rows)
            {
                r["WRK_LSL_ILOSC"] = DBNull.Value;
                r["WRK_LSL_PROCENTOWO"] = DBNull.Value;
            }

            if (rows.Length < 1)
            {
                this.ShowDxInfoDialog("Wybierz wiersze,");
                return;
            }

            multiThreadForm = new FormBackgroundWorkMultiThread("Szacowanie ...");
            multiThreadForm.BackgroundControl.SupportCancelation = true;
            multiThreadForm.BackgroundControl.ProgressType = ProgressType.Percentage;
            int max = Tools.Lotto.LottoLosowaniaTools.IloscLosowan;
            multiThreadForm.BackgroundControl.MaxProgress = max;
            progressReporter1.Form = multiThreadForm;

            Dictionary<int,int> dic = new Dictionary<int, int>();
            int del =10;
            while (max / del < 1 && del > 0)
            {
                del--;
            }
            int iloczyn = max / del;
            int reszta = max % del;
            int minNum = 0;
            int maxNum = iloczyn;

            for (int i=0; i < del; i++)
            {
                multiThreadForm.AddAction(new Action<int, int>(Szacuj), new object[] { minNum, maxNum });
                minNum = maxNum;
                maxNum += iloczyn;
            }
            if (reszta > 0)
            {
                multiThreadForm.AddAction(new Action<int, int>(Szacuj), new object[] { minNum, max });
            }
            //multiThreadForm.AddAction(new Action<int, int>(Szacuj), new object[] { 0, max });

            progressReporter1.Start();
            DialogResult dlg = multiThreadForm.ShowDialog();
            progressReporter1.Stop();
            switch (dlg)
            {
                case System.Windows.Forms.DialogResult.Cancel:
                    this.ShowDxInfoDialog("Przerwa na życzenie użytkownika");
                    break;
                case System.Windows.Forms.DialogResult.Abort:
                    this.ShowDxErrorDialog("Błąd wyliczania.");
                    break;
                case System.Windows.Forms.DialogResult.OK:
                    lottoStatystykiLosowanDataSet1.WRK_LOTTO_STATYSTYKI_LOSOWAN.Clear();
                    lottoStatystykiLosowanDataSet1.WRK_LOTTO_STATYSTYKI_LOSOWAN.AcceptChanges();
                    lottoStatystykiLosowanDataSet1.WRK_LOTTO_STATYSTYKI_LOSOWAN.Merge(copyDs.WRK_LOTTO_STATYSTYKI_LOSOWAN);
                    break;
            }
        }

        private void Szacuj(int minNum, int maxNum)
        {
            List<int> kombinacja = new List<int>();
            List<int> kombinacja2 = new List<int>();
            ActionLottoBase action;
            Dictionary<DataRow, int[]> dic = new Dictionary<DataRow, int[]>();
            Dictionary<DataRow, int> results = new Dictionary<DataRow, int>();
            foreach (DataRow r in rows)
            {
                dic.Add(r, new int[]{
                    r["WRK_LSL_X"].AsInt(),
                    r["WRK_LSL_Y"].AsInt(),
                    r["WRK_LSL_Z"].AsInt()});
                results.Add(r, 0);
            }
            for (int i=minNum; i < maxNum; i++)
            {
                kombinacja = Tools.Lotto.LottoLosowaniaTools.LosowaniaList[i];
                if (multiThreadForm.BackgroundControl.IsCanceling)
                    return;
                lock (lockDs)
                {
                    progressReporter1.Progress++;
                }
                kombinacja2.Clear();
                kombinacja2.AddRange(kombinacja);
                kombinacja2.Add(i);
                foreach (KeyValuePair<DataRow, int[]> kvp in dic)
                {
                    if (multiThreadForm.BackgroundControl.IsCanceling)
                        return;
                    action = ActionLottoBase.GetActionForLosowania(kvp.Key["WRK_LSL_TYP"].ToString());
                    if (action != null)
                    {
                        if (action.IsActionForLosowanie)
                        {
                            if (action.LiczbySpelniajaWarunki(kombinacja2, kvp.Value[0], kvp.Value[1], kvp.Value[2]))
                            {
                                results[kvp.Key] += 1;
                            }
                        }
                        else
                        {
                            if (action.LiczbySpelniajaWarunki(kombinacja, kvp.Value[0], kvp.Value[1], kvp.Value[2]))
                            {
                                results[kvp.Key] += 1;
                            }
                        }
                    }
                }
            }
            lock (lockDs)
            {
                foreach (KeyValuePair<DataRow, int> kvp in results)
                {
                    kvp.Key["WRK_LSL_ILOSC"] = kvp.Key["WRK_LSL_ILOSC"].AsInt(0) + kvp.Value;
                    kvp.Key["WRK_LSL_PROCENTOWO"] = kvp.Key["WRK_LSL_ILOSC"].AsDecimal() / multiThreadForm.BackgroundControl.MaxProgress.AsDecimal();
                }
            }
        }
        private void modeProvider1_CustomGetModes(object sender, ProgNetComponentsDx.Mode.CustomModeSettingsEventArgs e)
        {
            if (sender == colWRK_LSL_X||
                   sender == colWRK_LSL_Y ||
                   sender == colWRK_LSL_Z)
            {
                if (modeProvider1.CurrentMode == ProgNetComponentsDx.Enums.FormMode.Edit)
                {
                    if (!e.Row.CanRead())
                    {
                        e.IsReadOnly = true;
                        return;
                    }

                    ActionLottoBase action = ActionLottoBase.GetActionForLosowania(e.Row["WRK_LSL_TYP"].AsString());
                    if (action == null)
                    {
                        e.IsReadOnly = true;
                    }
                    else
                    {
                        if (sender == colWRK_LSL_X)
                            e.IsReadOnly = action.IsColReadOnly("X");
                        else if (sender == colWRK_LSL_Y)
                            e.IsReadOnly = action.IsColReadOnly("Y");
                        else if (sender == colWRK_LSL_Z)
                            e.IsReadOnly = action.IsColReadOnly("Z");
                    }
                }
                else
                {
                    e.IsReadOnly = true;
                }
            }
        }

        private void lueTyp_EditValueChanged(object sender, EventArgs e)
        {
            string typ = lueTyp.EditValue.AsString();
            ActionLottoBase action = ActionLottoBase.GetActionForLosowania(typ);
            if (action != null)
            {
                meTyp.Text = action.Opis.ReplaceSingleEOL();
            }
            else
            {
                meTyp.Text = "";
            }
        }

        private void gvMain_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            if (e.Column == colWRK_LSL_X ||
                e.Column == colWRK_LSL_Y ||
                e.Column == colWRK_LSL_Z)
            {
                gvMain.SetRowCellValue(e.RowHandle, colWRK_LSL_PROCENTOWO, DBNull.Value);
                gvMain.SetRowCellValue(e.RowHandle, colWRK_LSL_ILOSC, DBNull.Value);
            }
            else if (e.Column == colWRK_LSL_TYP)
            {
                gvMain.SetRowCellValue(e.RowHandle, colWRK_LSL_X, DBNull.Value);
                gvMain.SetRowCellValue(e.RowHandle, colWRK_LSL_Y, DBNull.Value);
                gvMain.SetRowCellValue(e.RowHandle, colWRK_LSL_Z, DBNull.Value);
            }
        }

        private void gvMain_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            DataRow row = gvMain.GetDataRow(e.FocusedRowHandle);
            if (row.CanRead())
            {
                lueTyp.EditValue = row["WRK_LSL_TYP"].AsString();
            }
        }

        private void btnPrzeliczLiczby_Click(object sender, EventArgs e)
        {
            if (!LottoLosowaniaTools.NajczestszeLiczbyPrecashed)
            {
                LottoLosowaniaTools.GetNajczestszeLiczby(1);
            }
            gridControl1.DataSource = LottoLosowaniaTools.NajczestszeLiczbyClone;
        }

        private void btnPrzeliczPary_Click(object sender, EventArgs e)
        {
            if (!LottoLosowaniaTools.NajczestszeDwojkiPrecashed)
            {
                LottoLosowaniaTools.GetNajczestszeLiczby(2);
            }
            gridControl2.DataSource = LottoLosowaniaTools.NajczestszeDwojkiClone;
        }

        private void btnPrzeliczTrojki_Click(object sender, EventArgs e)
        {
            if (!LottoLosowaniaTools.NajczestszeTrojkiPrecashed)
            {
                LottoLosowaniaTools.GetNajczestszeLiczby(3);
            }
            gridControl3.DataSource = LottoLosowaniaTools.NajczestszeTrojkiClone;
        }

    }
}
